package vip.ola.code.ctrl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import vip.ola.code.common.ctrl.BaseController;
import vip.ola.code.common.service.RpcCommonService;
import vip.ola.code.secruity.JwtUser;
import vip.ola.core.common.annotation.MethodLog;
import vip.ola.core.common.constant.CodeConstant;
import vip.ola.core.common.constant.Constant;
import vip.ola.core.common.domain.BizResponse;
import vip.ola.core.common.domain.PayResponse;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.entity.code.CodeUser;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

import static vip.ola.core.common.constant.CodeConstant.*;
import static vip.ola.core.common.constant.Constant.CODE_ROLE_NORMAL;
import static vip.ola.core.common.constant.RetEnum.*;
import static vip.ola.core.common.constant.SysConfigConstant.*;

@RestController
@RequestMapping(Constant.CODE_CONTROLLER_ROOT_PATH + "/user")
@PreAuthorize("hasRole('" + CODE_ROLE_NORMAL + "')")
public class UserController extends BaseController {

    private final static MyLog _log = MyLog.getLog(UserController.class);

    @Autowired
    private RpcCommonService rpcService;

    @RequestMapping("/list")
    public ResponseEntity<?> list(LocalDateTime createTimeStart, LocalDateTime createTimeEnd, String username, String realName,
                                  String mobile, Integer type, Integer status) {
        CodeUser codeUser = getCodeUser();
        codeUser.setType(type);
        codeUser.setStatus(status);
        codeUser.setUsername(username);
        codeUser.setRealName(realName);
        codeUser.setMobile(mobile);
        codeUser.setCreateTime(createTimeStart);
        codeUser.setUpdateTime(createTimeEnd);
        IPage<CodeUser> page = rpcService.codeUserService.list(getPageIndex(), getPageSize(), codeUser);
        return ResponseEntity.ok(PayResponse.buildPageSuccess(page));
    }

    @RequestMapping("/count")
    public ResponseEntity<?> count(LocalDateTime createTimeStart, LocalDateTime createTimeEnd, String username, String realName,
                                  String mobile, Integer type, Integer status) {
        CodeUser codeUser = getCodeUser();
        codeUser.setType(type);
        codeUser.setStatus(status);
        codeUser.setUsername(username);
        codeUser.setRealName(realName);
        codeUser.setMobile(mobile);
        codeUser.setCreateTime(createTimeStart);
        codeUser.setUpdateTime(createTimeEnd);
        Map map = rpcService.codeUserService.count(getPageIndex(), getPageSize(), codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(map));
    }

    @RequestMapping("/get")
    public ResponseEntity<?> get(Long id) {
        CodeUser codeUser = getCodeUser();
        codeUser.setId(id);
        codeUser = rpcService.codeUserService.getByCodeUser(codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(codeUser));
    }

    @MethodLog(remark = "添加用户")
    @RequestMapping("/add")
    public ResponseEntity<?> add(CodeUser codeUser) {
        CodeUser byName = rpcService.codeUserService.getByName(codeUser.getUsername());
        if (byName != null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USERNAME_ALREADY_EXIST));
        }
        JwtUser user = getUser();
        CodeUser loginUser = rpcService.codeUserService.getById(user.getId());
        codeUser.setRate(codeUser.getRate().divide(new BigDecimal("100")));
        ResponseEntity entity = validate(codeUser, loginUser);
        if (entity != null) {
            return entity;
        }
        if (CODE_CODE_TYPE.equals(user.getType())) {
            codeUser.setCodeBusId(loginUser.getId());
            codeUser.setCodeBusRate(loginUser.getRate());
            if (CODE_CODE_SUB_TYPE.equals(codeUser.getType())) {
                // 码商添加子账号
                codeUser.setRate(loginUser.getRate());
                codeUser.setDeposit(loginUser.getDeposit());
            }
        } else if (CODE_CODE_SUB_TYPE.equals(user.getType())) {
            codeUser.setCodeBusId(loginUser.getCodeBusId());
            codeUser.setCodeBusRate(loginUser.getCodeBusRate());
        } else if (CODE_AGENT_TYPE.equals(user.getType())) {
            // 代理码商添加会员
            codeUser.setCodeBusId(loginUser.getCodeBusId());
            codeUser.setCodeBusRate(loginUser.getCodeBusRate());
            codeUser.setAgentId(loginUser.getId());
            codeUser.setAgentRate(loginUser.getRate());
        }
        codeUser.setStatus(CODE_STATUS_OK);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        codeUser.setPassword(encoder.encode(codeUser.getPassword()));
        codeUser.setBalance(null);
        codeUser.setTotalCollNum(null);
        codeUser.setTotalCollAmount(null);
        codeUser.setTotalCollProfit(null);

        codeUser.setRole(ROLE_CODE_NORMAL);
        codeUser.setCreateId(loginUser.getId());
        codeUser.setCreateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeUserService.add(codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    @MethodLog(remark = "修改用户信息")
    @RequestMapping("/edit")
    public ResponseEntity<?> edit(CodeUser codeUser) {
        JwtUser user = getUser();
        CodeUser loginUser = rpcService.codeUserService.getById(user.getId());
        if (codeUser.getId().equals(loginUser.getId())) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_NOT_UPDATE_SELF));
        }
        codeUser.setRate(codeUser.getRate().divide(new BigDecimal("100.00")));
        ResponseEntity entity = validate(codeUser, loginUser);
        if (entity != null) {
            return entity;
        }
        if (StringUtils.isNotBlank(codeUser.getPassword())) {
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            codeUser.setPassword(encoder.encode(codeUser.getPassword()));
        } else {
            codeUser.setPassword(null);
        }
        codeUser.setType(null);
        codeUser.setUsername(null);
        codeUser.setStatus(null);
        codeUser.setBalance(null);
        codeUser.setTotalCollNum(null);
        codeUser.setTotalCollAmount(null);
        codeUser.setTotalCollProfit(null);
        codeUser.setAgentId(null);
        codeUser.setAgentRate(null);
        codeUser.setCodeBusId(null);
        codeUser.setCodeBusRate(null);
        codeUser.setUpdateTime(LocalDateTime.now());
        boolean isOk = rpcService.codeUserService.update(codeUser);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    private ResponseEntity validate(CodeUser codeUser, CodeUser loginUser) {
        JwtUser user = getUser();
        Integer loginType = user.getType();
        if (loginUser == null && CODE_STATUS_OK.equals(loginUser.getStatus())) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_NOT_EXIST));
        }
        if (codeUser.getRate().compareTo(loginUser.getRate()) == 1) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_RATE_EXORBITANCE_ERROR));
        }
        JSONObject json = rpcService.rpcSysConfigService.getSysConfigObj(TYPE_CODE);
        if (codeUser.getDayMaxAmount().compareTo(json.getBigDecimal(USER_DAY_MAX_AMOUNT)) == 1) {
            return ResponseEntity.ok(BizResponse.build(CODE_DAY_MAX_AMOUNT_ERROR));
        }
        if (codeUser.getDayMaxNum() > json.getInteger(USER_DAY_MAX_NUM)) {
            return ResponseEntity.ok(BizResponse.build(CODE_DAY_MAX_NUM_ERROR));
        }
        if (loginType.equals(codeUser.getType())) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_SAME_ERROR));
        }
        if (CODE_USER_TYPE.equals(loginType)) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_USER_ERROR));
        } else if (CODE_AGENT_TYPE.equals(loginType)) {
            if (CODE_AGENT_TYPE.equals(codeUser.getType())) {
                return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_AGENT_ERROR));
            }
            if (CODE_CODE_SUB_TYPE.equals(codeUser.getType())) {
                return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_CODE_SUB_ERROR));
            }
            if (CODE_CODE_TYPE.equals(codeUser.getType())) {
                return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_CODE_BUS_ERROR));
            }
        } else if (CodeConstant.CODE_CODE_SUB_TYPE.equals(loginType)) {
            if (CODE_CODE_TYPE.equals(codeUser.getType())) {
                return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_CODE_BUS_ERROR));
            }
        }
        return null;
    }

    @MethodLog(remark = "删除用户余额")
    @RequestMapping("/del")
    public ResponseEntity<?> del(long id) {
        CodeUser codeUser = getCodeUser();
        codeUser.setId(id);
        codeUser = rpcService.codeUserService.getByCodeUser(codeUser);
        if (getUser().getId().equals(id)) {
            return ResponseEntity.ok(BizResponse.build(RET_COMM_RECORD_NOT_AUTH));
        }
        if (codeUser == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_USER_ERROR));
        }
        boolean isOk = rpcService.codeUserService.removeById(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    @MethodLog(remark = "清理用户余额")
    @RequestMapping("/clean")
    public ResponseEntity<?> clean(long id) {
        CodeUser codeUser = getCodeUser();
        codeUser.setId(id);
        codeUser = rpcService.codeUserService.getByCodeUser(codeUser);
        if (getUser().getId().equals(id)) {
            return ResponseEntity.ok(BizResponse.build(RET_COMM_RECORD_NOT_AUTH));
        }
        if (codeUser == null) {
            return ResponseEntity.ok(BizResponse.build(CODE_USER_AUTH_OPERATE_USER_ERROR));
        }
        boolean isOk = rpcService.codeUserService.cleanAmount(id);
        return ResponseEntity.ok(PayResponse.buildSuccess(isOk));
    }

    private CodeUser getCodeUser() {
        JwtUser user = getUser();
        CodeUser codeUser = new CodeUser();
        Integer type = user.getType();
        if (CODE_USER_TYPE.equals(type)) {
            codeUser.setId(user.getId());
            codeUser.setAgentId(user.getAgentId());
            codeUser.setCodeBusId(user.getCodeBusId());
        } else if (CODE_AGENT_TYPE.equals(type)) {
            codeUser.setAgentId(user.getId());
            codeUser.setCodeBusId(user.getCodeBusId());
        } else if (CODE_CODE_SUB_TYPE.equals(type)) {
            codeUser.setCodeBusId(user.getCodeBusId());
        } else if (CODE_CODE_TYPE.equals(type)) {
            codeUser.setCodeBusId(user.getId());
        }
        codeUser.setDeleted(LOGIC_NOT_DELETE);
        return codeUser;
    }

}